1. Field of the Invention
This invention relates graphical user interfaces, and, more specifically to the generation of components of a graphical user interface.
2. Background Art
A software application typically includes a graphical user interface (GUI) for displaying the application""s output and receiving user input that consists of GUI components. Examples of GUI component types include menu, scroll bar, text field, button, check box, list, and label. There are a number of software vendors that have developed GUI libraries that consist of software modules that implement GUI components. Mechanisms are provided to access a GUI library to incorporate the desired GUI component from the library for use with the software application to generate a piece of the application""s GUI. The mechanisms currently available for accessing a vendor""s GUI library limit the application developer to one GUI library. That is, it is impossible to intermingle one vendor""s GUI components with another vendor""s GUI components. Further, it is impossible to customize an application""s GUI by replacing one component of the GUI with another GUI component.
One technique, or mechanism, that has been used in the object-oriented environment for accessing a vendor""s GUI library is referred to as the factory technique. A factory creates or produces objects at runtime. The factory technique is described below with reference to an abstract factory. implementation and a factory method implementation. Neither the abstract factory nor the factory method implementations allow a software application to intermingle GUI components from different vendor""s GUI libraries.
Abstract Factory
An abstract factory is implemented in an object-oriented environment using factory and product abstract classes that define the operations or methods to be implemented by their concrete subclasses. The factory includes methods that are used to create an instance of a product concrete subclass. A product concrete subclass is a specific GUI component and includes the GUI component""s operations.
An abstract factory can be used, for example, to allow an application developer to write a software application that contains references to the GUI components of a generic GUI library. At run time, the GUI library is specified and the GUI component references are resolved to refer to GUI components in the specified GUI library. Using this technique, a software application can be written to use one GUI library""s GUI components (e.g., Motif GUI components) in one runtime environment and another GUI library""s GUI components (e.g., Presentation Manager GUI components) in another runtime environment.
To instantiate Motif""s scroll bar without using the abstract factory technique, the following C++ code can be used:
(1) ScrollBar* sb=new MotifScrollBar;
The above code statement is not advantageous because it hard-codes the Motif standard into the application. Instead, the following code can be used to create a scroll bar GUI component:
(2) ScrollBar* sb=guiFactoryxe2x88x92 greater than CreateScrollBar( );
In this case, guiFactory can be an instance of either the MotifFactory or the PMFactory concrete class both of which are subclasses of a GUIFactory abstract class. FIG. 1 provides an example of the abstract product classes and concrete subclasses used in the abstract factory design pattern. There are three abstract classes, GUIFactory 102, Menu 112 and ScrollBar 122. Since they are abstract classes, they are not instantiated at runtime.
GUIFactory 102 is an abstract class that specifies methods for creating GUI components (e.g. scroll bar, window, and button) such as the CreateMenu and CreateScrollBar methods. GUIFactory 102 is referred to as a factory because it specifies methods for producing objects. Subclasses of GUIFactory 102 define a specific implementation of the methods defined by GUIFactory 102. Two subclasses of GUIFactory 102 which are concrete factories (i.e., create concrete product objects) are MotifFactory 104 and PMFactory 106. MotifFactory 104 provides a Motif-specific implementation of the same method in GUIFactory 102. PMFactory 106 defines a Presentation Manager-specific implementation of the method.
One of the concrete factories is instantiated at runtime based on the look-and-feel standard that is specified (e.g., as a runtime parameter). If, for example, the look-and-feel standard is determined at runtime to be Motif, an instance of MotifFactory is instantiated. The second code statement provided above would have the effect of invoking the CreateScrollBar method or operation of the MotifFactory object which would create a scroll bar having the Motif look-and-feel.
The other two abstract classes, Menu 112 and ScrollBar 122 define the methods that are implemented by a concrete subclass. For example, MotifMenu 114 and PMMenu 116 define specific implementations of the Popup operation defined by Menu 112 based on their respective look-and-feel standards. Similarly, the ScrollTo operation defined in the Scroll Bar 122 abstract class is implemented by MotifScrollBar 124 and PMScrollBar 126. In the above example, the second code statement would invoke the CreateScrollBar method of MotifFactory 104 that would result in the creation of an instance of MotifScrollBar 124.
The abstract factory uses factory and product abstract classes to define the methods that are implemented by their respective concrete classes. An application does not directly instantiate classes. Instead, objects can be instantiated indirectly as illustrated by the second code statement. The application effectively uses a pointer to the object to be instantiated that is resolved at runtime.
The abstract factory mechanism thereby eliminates the situation where the application is forced to use one look-and-feel standard or another. However, the application must select one look-and-feel standard and use only that standard""s GUI components. It is not possible, for example, to have both a scroll bar that has the Motif look-and-feel (i.e., MotifScrollBar 124) and PM scroll bar (i.e., PMScrollBar 126) GUI component in the same application using the abstract factory mechanism. Further, all of the classes are defined for the application prior to runtime. Thus, it is not possible to modify the class architecture by inserting, for example, new subclasses of Menu 112 or ScrollBar 122 at runtime.
Factory Method
In the abstract factory approach, a factory object is instantiated that knows the type of product objects that can be constructed. The product object""s constructor is used to construct the product object. Another factory mechanism that has the same drawbacks as the abstract factory is referred to as a Factory Method. The Factory method is implemented by specifying in the abstract object a call to a method that creates the product instead of calling a constructor. The function that creates the product object is referred to as a factory method because it xe2x80x9cmanufacturesxe2x80x9d (or creates) the product object. The factory method is used instead of a constructor to create a product object. FIG. 2 provides an example of a factory method class architecture.
The architecture in FIG. 2 illustrates a framework that produces GUI components from a vendor""s GUI library of GUI components. There are two abstract classes, an abstract creator class (i.e., GUI 202) and an abstract product class (GUIComponent 212). GUI 202 includes a factory method declaration (i.e., createUI). However, GUI 202 does not know what type of product it should create (i.e., GUI 202 cannot call a constructor method for MotifComponent 214 or PMComponent 216).
The factory method of GUI 202 is redefined in two concrete creator object subclasses of application 202 (i.e., MotifUI 204 and PMUI 206). MotifUI 204 defines a createUIComponent factory method to create an instance of MotifComponent 214. Similarly, PMUI 206 defines a createUIComponent factory method to create an instance of PMComponent 216.
Like the abstract factory, the factory method mechanism requires that the creator and product classes be defined and known prior to runtime. That is, the class architecture is known and defined prior to runtime. It is not possible, for example, to modify the class architecture by inserting a new subclass of the abstract creator or product classes (i.e., GUI 202 and GUIComponent 212).
In both the factory method and abstract factory approaches, a factory produces a GUI from a single vendor""s GUI library. Therefore, a GUI produced by a traditional factory has a single look-and-feel. Therefore, an application that uses the traditional factory approach to generate its GUI is limited to a GUI that has a single look-and-feel. For example, a GUI that is produced by concrete factory 104 has a Motif look-and-feel while concrete factory 106 produces a Presentation Manager look-and-feel. Similarly, in the factory method approach, a concrete creator (e.g., MotifUI 204 or PMUI 206) that is used to create a GUI creates a GUI components from a single look and feel. For example, the createUIComponent method of MotifUI 204 creates a MotifComponent 214. FIG. 3 illustrates the traditional factory approach.
Application environment 306 contains GUI 332 that was created by traditional factory 302. Factory 302 contains a look-and-feel that is generated by view components Va1-Van of GUI library 312. Therefor, GUI 332 offers a single look-and-feel. Similarly, application environment 304 contains GUI 324 created by factory 302. GUI 324 has a single look-and-feel that is generated by view components Vb1-Vbn of GUI library 312. It is not possible for GUI 332 or GUI 324 to contain a scroll bar GUI component having a Motif look-and-feel and a scroll bar GUI component having a PM look-and-feel in the same application using the factory method mechanism.
Further, GUIs 332 and 324 are static implementations that are woven into an application""s program code. Unless the application""s program code is modified, GUIs 332 and 324 provide the same look-and-feel each time the application program is invoked. One example of such an application is the Explorer in Microsoft""s Windows 95 product. A tree control is provided in the Explorer that allows the user to browse files, etc. Each node of the tree is comprised of an icon and a label. The icon and the text of the label can be changed. However, it would be necessary to modify the program code to change the look-and-feel for a node of the tree. For example, without modifying the program code, it is not possible to provide a GUI in which a node can either use the standard look-and-feel (i.e., an icon and a label) or adopt a new look-and-feel (e.g., button that lauches an application, a GUI component that provides a preview of the item to which the tree node is associated by displaying text, or playing a video clip, or displaying a picture).
Model View Control Paradigm
In the Smalltalk-80 programming language, a mechanism is used to implement graphical user interfaces (GUIs) that is referred to as Model/View/Controller or MVC. In MVC, the functions performed in conjunction with a GUI are split into separate programming modules, or objects. FIG. 4 provides an illustration of the objects in the MVC paradigm.
Model 404 is the application object. Model 404 is, for example, a clock application that keeps track of a time by updating an internal record of time every second. View 406 implements the screen representation portion of the GUI. For example, view 406 can be comprised of a digital clock GUI component that displays a digital readout of the time maintained by model 404. Controller 402 provides the mechanism for responding to input received via the GUI. View 406 uses Controller 402 to implement its response strategy.
Controller 402 receives and interprets input such as a mouse click or keyboard input. For example, if controller 402 interprets keyboard input as a value to be used to reset the clock, it calls a method (e.g., setTime) of Model 404 to change the internal record of time stored by Model 404. Controller 402 might send a change message directly to view 406 even though the model hasn""t changed. For example, controller 402 may interpret user input as a request to reorder a list displayed by view 406. In this case, controller 402 sends the reformat message to view 406 to resort the list.
When a change is made to the model such as in the case of the setTime operation, the change must be sent to view 406. A subscribe/notify protocol is implemented between model 404 and view 406. View 406 invokes the attach method of model 404 to register as being xe2x80x9cinterestedxe2x80x9d in the data maintained by model 404. Whenever the data in model 404 changes, model 404 notifies view 406. View 406 invokes the retrieveTime method of model 404 to retrieve the changed data and then displays the modifications. View 406 can send a detach message to model 404 to discontinue notifications from model 404.
In the SmallTalk paradigm, view 406 comprises an integral set of GUI components that includes a specific clock display GUI component (e.g., digital display GUI component). It is not possible to modify the integral set of GUI components to replace the clock display GUI component without modifying the program code that implements view 406. Thus, it is not possible to plug in an analog clock display GUI component to replace the digital display without modifying the program code that implements view 406.
Embodiments of the invention are used to customize a graphical user interface (GUI) that represents the view in a Model/View/Controller architecture. The model contains an application""s data and one or more structural components that are used to identify the GUI components of the view. A factory builds the GUI using characteristics of the structural components to identify a set of GUI components to create the view.
The factory can build a view using GUI components from multiple look-and-feel standards (e.g., Motif, Presentation Manager, Microsoft Windows, or Macintosh). A GUI component can be added to the set of GUI components known to the factory. The factory is instructed to use a GUI component for a given characteristic of a structural component.
In an embodiment of the invention, object-oriented programming is used. The model, view, controller and factory are implemented as software modules known as objects that include methods for performing logical functionality. The model has a document object that includes methods for modifying the application data contained in the model and notifying the view when a modification has occurred. The structural components of the model are implemented as an Element object class that represents a subset of a structural tree defined by the model""s structural components. An element includes methods for traversing the tree and retrieving information about the tree. An attributes object class stores the characteristics associated with a structural element, or the model as a whole.
The view is comprised of a plurality of instances of a view fragment object class that implement GUI components. The factory includes methods for creating a view fragment instance using the attributes of an element of the model. A create method of the factory is invoked for a given element. The factory can query the element to retrieve its attributes. The factory uses the element""s attributes to identify the GUI component object class to instantiate as a view fragment of the view.
The create method of the factory can be invoked by the view. For example, the create method can be invoked by a view fragment of the view to create other view fragments for the view. A view fragment may delegate to a child view fragment. The view fragment can invoke the factory to create the child view fragment. Thus, the view builds a structure comprised of view fragments. Since the view structure is created by the view, its structure can be different than the model structure. Further, the model is unaware of the structure of the view.
A view fragment includes methods for managing its portion of the GUI. In addition, a view fragment can be queried to determine the structural element to which it is mapped and the document associated with the view in which the view fragment is created. A change in the model can cause a change in the GUI. Additional view fragments can be added to the view as a result of a change in the model, for example. The view fragment includes methods for receiving a notification of a change in the model.
Model change notification is performed in embodiments of the invention using a listener object and a documentEvent object. The documentEvent includes information about the change (e.g., the name of the document that changed, the area of the document that changed and the edit history). The notification message that is sent to a view fragment contains the documentEvent.
The listener includes methods for forwarding a change notification that it receives from the model the view fragments contained in the view. To receive a notification from the model, the listener registers with the model. To discontinue receiving notifications, the listener can request the model to remove it from the models set of listeners.
The listener forwards a change notification to a parent view fragment. The parent view fragment determines whether any of its child view fragments are affected by the change. If so, the parent forwards the change notification to the child view fragment. The child view fragment is passed to the factory to use if the child view fragment needs to create a new view fragment.